Background

Analysis task

A. Logit model without segmentation

  • a.Calculate own- and cross-price elasticities.Do you see any particular patterns?
  • b.Calculate optimal prices for KB and KR (note that you have two products) to maximize the profit when Mango price is P(MB)=1.43

B. Logit model with segmentation

  • a.Calculate own- and cross-price elasticities.
    • How does it differ from the no-segmentation case?
    • Which products are closer substitutes?
  • b.Calculate optimal prices
    • Not to launch KB—what is the optimal price of KR (P(MB)=1.43)
    • launch KB—what is the optimal price of KR and KB (P(MB)=1.43)

###C. Understanding strategic responses * a.Calculate MB’s optimal price given KB and KR ’s optimal prices. * b.React to MB’s new price, set new price for KB and KR. * c.Repeat previous two steps, until reach “equilibrium price”.

Part A : Logit model without segmentation

#Run MLE.
mlogitdata=mlogit.data(data,id="id",varying=4:7,choice="choice",shape="wide")
mle= gmnl(choice ~ price, data = mlogitdata)
coef=mle$coefficients
summary(mle)
## 
## Model estimated on: Fri Jun 03 19:46:24 2022 
## 
## Call:
## gmnl(formula = choice ~ price, data = mlogitdata, method = "nr")
## 
## Frequencies of categories:
## 
##       0      KB      KR      MB 
## 0.41564 0.18035 0.20039 0.20362 
## 
## The estimation took: 0h:0m:0s 
## 
## Coefficients:
##                Estimate Std. Error z-value  Pr(>|z|)    
## KB:(intercept)  4.25316    0.32821  12.959 < 2.2e-16 ***
## KR:(intercept)  4.36240    0.32945  13.241 < 2.2e-16 ***
## MB:(intercept)  4.20440    0.31331  13.419 < 2.2e-16 ***
## price          -3.73793    0.23671 -15.791 < 2.2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Optimization of log-likelihood by Newton-Raphson maximisation
## Log Likelihood: -1909
## Number of observations: 1547
## Number of iterations: 4
## Exit of MLE: gradient close to zero (gradtol)

The β here is related to how popular the product is. The baseline popularity of each product is almost identical. This is because all products are selected roughly at the same rate. βKR is slightly higher than βKB and βMB, means that KR gets selected a little more often.

# Calculate own- and cross-price elasticities for all combination of products

beta0KB = as.numeric(coef[1])
beta0KR = as.numeric(coef[2])
beta0MB = as.numeric(coef[3])
beta1 = as.numeric(coef[4])

para=c(beta0KB,beta0KR,beta0MB,beta1)

#Average Price
avgPriceKB = mean(data$price.KB)
avgPriceKR = mean(data$price.KR)
avgPriceMB = mean(data$price.MB)
avgPriceAll=c(avgPriceKB,avgPriceKR,avgPriceMB)
#Define choice probability for each product as a function of parameters.
qfunKB=function(priceKB,priceKR,priceMB,para){
    prob=exp(para[1]+para[4]*priceKB)/(1+exp(para[1]+para[4]*priceKB)+exp(para[2]+para[4]*priceKR)+exp(para[3]+para[4]*priceMB))
    return(prob)
}

qfunKR=function(priceKB,priceKR,priceMB,para){
    prob=exp(para[2]+para[4]*priceKR)/(1+exp(para[1]+para[4]*priceKB)+exp(para[2]+para[4]*priceKR)+exp(para[3]+para[4]*priceMB))
    return(prob)
}

qfunMB=function(priceKB,priceKR,priceMB,para){
    prob=exp(para[3]+para[4]*priceMB)/(1+exp(para[1]+para[4]*priceKB)+exp(para[2]+para[4]*priceKR)+exp(para[3]+para[4]*priceMB))
    return(prob)
}
#Define Demand Function
demandKB = qfunKB(avgPriceKB,avgPriceKR,avgPriceMB,para) 
demandKR = qfunKR(avgPriceKB,avgPriceKR,avgPriceMB,para)  
demandMB = qfunMB(avgPriceKB,avgPriceKR,avgPriceMB,para)
#Calculate elasticity
#Own-price elasticity
ownElasticityKB = -(beta1)*avgPriceKB*(1-demandKB) 
ownElasticityKR = -(beta1)*avgPriceKR*(1-demandKR) 
ownElasticityMB = -(beta1)*avgPriceMB*(1-demandMB) 

#Cross-elasticities
crossElasticityKB = -(beta1)*avgPriceKB*demandKB
crossElasticityKR = -(beta1)*avgPriceKR*demandKR 
crossElasticityMB = -(beta1)*avgPriceMB*demandMB 

#create a data frame that includes all the elasticities
dfElasticity <- data.frame("Product"=c("KB","KR","MB"),
                           "OwnElasticity"=c(ownElasticityKB,ownElasticityKR,ownElasticityMB),
                           "CrossPriceElasticity"=c(crossElasticityKB,crossElasticityKR,crossElasticityMB))
dfElasticity
##   Product OwnElasticity CrossPriceElasticity
## 1      KB      4.257847            0.9054743
## 2      KR      4.131270            1.0199225
## 3      MB      4.069547            0.9601564
##Calculate optimal prices for KB and KR (note that you have two products) to maximize the profit when Mango price is PMB = 1.43.

#Define unit cost, price of mango bubbles, and market size
uc=0.5
priceMB=1.43
size=1000
para=c(beta0KB,beta0KR,beta0MB,beta1)
#Define demand
demand_KB_KR=function(priceKB,priceKR,priceMB,para){
    probKB=exp(para[1]+para[4]*priceKB)/(1+exp(para[1]+para[4]*priceKB)+exp(para[2]+para[4]*priceKR)+exp(para[3]+para[4]*priceMB))
    probKR=exp(para[2]+para[4]*priceKR)/(1+exp(para[1]+para[4]*priceKB)+exp(para[2]+para[4]*priceKR)+exp(para[3]+para[4]*priceMB))
    return(cbind(probKB,probKR))
}
#Define profit
profit_KB_KR=function(priceKB,priceKR,priceMB,para){
    profitKB=size*(demand_KB_KR(priceKB,priceKR, priceMB,para)[,1]*(priceKB-uc))
    profitKR=size*(demand_KB_KR(priceKB,priceKR, priceMB,para)[,2]*(priceKR-uc))
    return(cbind(profitKB,profitKR))
}
#Choose space of prices to search for the optimal price over
aux=seq(1,3,0.01)
#Because we search over two dimensions, create complete combination of the two prices
pricespace=expand.grid(aux,aux)

profitmat=matrix(0L,nrow(pricespace),1)

for (i in 1:nrow(pricespace)){
    profitmat[i]=sum(profit_KB_KR(pricespace[i,1],pricespace[i,2],priceMB,para))  
}

#Draw figure
xaxis=list(title="P^{KB}")
yaxis=list(autorange = "reversed",title="P^{KR}")
zaxis=list(title="Profit")
p=plot_ly(x=pricespace[,1],y=pricespace[,2],z=as.numeric(profitmat),
                type="scatter3d",mode="markers",
          marker = list(color = as.numeric(profitmat), colorscale = c('#FFE1A1', '#683531'), showscale = TRUE))%>%
            layout(scene=list(xaxis=xaxis,yaxis=yaxis,zaxis=zaxis))%>%
            config(mathjax = 'cdn')
p
print(max(profitmat))
## [1] 393.4082
print(pricespace[profitmat==max(profitmat)])
## [1] 1.16 1.16

The max profit is 393.408 and the optimal price for KB and KR is 1.16.

Part B : Logit model with segmentation

#Run non-segment MLE
mlogitdata=mlogit.data(data,id="id",varying=4:7,choice="choice",shape="wide")
mle_noseg= gmnl(choice ~  price, data = mlogitdata)
coef_noseg=mle_noseg$coefficients
summary(mle_noseg)
## 
## Model estimated on: Fri Jun 03 19:46:26 2022 
## 
## Call:
## gmnl(formula = choice ~ price, data = mlogitdata, method = "nr")
## 
## Frequencies of categories:
## 
##       0      KB      KR      MB 
## 0.41564 0.18035 0.20039 0.20362 
## 
## The estimation took: 0h:0m:0s 
## 
## Coefficients:
##                Estimate Std. Error z-value  Pr(>|z|)    
## KB:(intercept)  4.25316    0.32821  12.959 < 2.2e-16 ***
## KR:(intercept)  4.36240    0.32945  13.241 < 2.2e-16 ***
## MB:(intercept)  4.20440    0.31331  13.419 < 2.2e-16 ***
## price          -3.73793    0.23671 -15.791 < 2.2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Optimization of log-likelihood by Newton-Raphson maximisation
## Log Likelihood: -1909
## Number of observations: 1547
## Number of iterations: 4
## Exit of MLE: gradient close to zero (gradtol)
#set seed
set.seed(0)

#Number of individuals
N = 359

#Clustering
demo_cluster = kmeans(x=demo[, 2:18], centers = 8, nstart = 1000)
cluster_id = data.frame(id = demo$id)
cluster_id$cluster = demo_cluster$cluster
data = merge(data, cluster_id, by = "id", all.x = T)

# for those who don't fit in any cluster, group them into one additional cluster
data$cluster[is.na(data$cluster)] = 9
# Segment share
seg.share = c( table(demo_cluster$cluster),N - sum(table(demo_cluster$cluster))) / N
seg.share 
##          1          2          3          4          5          6          7 
## 0.10863510 0.13091922 0.10584958 0.06406685 0.08635097 0.11142061 0.09470752 
##          8            
## 0.08635097 0.21169916
# Store the coefficients (you can store many other things)
coef.est = data.frame(segment = 1:9, intercept.KB = NA, intercept.KR = NA, 
                      intercept.MB = NA, price.coef = NA) 
#Write a for-loop. 
for (seg in 1:9) {
    # During each loop, pick subset of data of consumers from each segment.
    data.sub = subset(data, cluster == seg)
    
    #Using that data, the rest remains the same.
    mlogitdata=mlogit.data(data.sub,id="id",varying=4:7,choice="choice",shape="wide")
    
    #Run MLE.
    mle= gmnl(choice ~  price, data = mlogitdata)
    mle
    #Store the outcome in the coef.est matrix.
    coef.est[seg, 2:5] = mle$coefficients
}

#Plot results
demand=function(priceKB,priceKR,priceMB,para){
    prob=exp(para[1]+para[4]*priceKB)/(1+exp(para[1]+para[4]*priceKB)+exp(para[2]+para[4]*priceKR)+exp(para[3]+para[4]*priceMB))
    return(prob)
}

pricespace=seq(0.5,1.8,0.01)
plot(pricespace,demand(pricespace,mean(data$price.KR),mean(data$price.MB),as.numeric(coef.est[3,2:5])),type='l',xlab='Prices',
     ylab='Probability of purchase',col="blue",lwd=20*seg.share[1],
     cex=2,cex.lab=1.5, cex.axis=1.5, cex.main=1.5, cex.sub=1.5)
lines(pricespace,demand(pricespace,mean(data$price.KR),mean(data$price.MB),as.numeric(coef.est[1,2:5])),col="blue",lwd=20*seg.share[3])
lines(pricespace,demand(pricespace,mean(data$price.KR),mean(data$price.MB),as.numeric(coef.est[4,2:5])),col="red",lwd=20*seg.share[4])
lines(pricespace,demand(pricespace,mean(data$price.KR),mean(data$price.MB),as.numeric(coef.est[5,2:5])),col="green",lwd=20*seg.share[5])
lines(pricespace,demand(pricespace,mean(data$price.KR),mean(data$price.MB),as.numeric(coef.est[6,2:5])),col="orange",lwd=20*seg.share[6])
lines(pricespace,demand(pricespace,mean(data$price.KR),mean(data$price.MB),as.numeric(coef.est[2,2:5])),col="black",lwd=20*seg.share[2])
lines(pricespace,demand(pricespace,mean(data$price.KR),mean(data$price.MB),as.numeric(coef.est[7,2:5])),col="purple",lwd=20*seg.share[2])
lines(pricespace,demand(pricespace,mean(data$price.KR),mean(data$price.MB),as.numeric(coef.est[8,2:5])),col="brown",lwd=20*seg.share[2])
lines(pricespace,demand(pricespace,mean(data$price.KR),mean(data$price.MB),as.numeric(coef.est[9,2:5])),col="sky blue",lwd=20*seg.share[2])

For this part, we choose to segment the customers into 9 clusters because when increase the clusters to 10 or more, the least proportion which is segment 4, would further decrease.As a result, it could contain less than 60 people per cluster, which would be less reliable for the estimation.

#Calculate elasticity

#Define aggregated demand funtion
demand_3=function(priceKB,priceKR,priceMB,para){
    probKB=exp(para[1]+para[4]*priceKB)/(1+exp(para[1]+para[4]*priceKB)+exp(para[2]+para[4]*priceKR)+exp(para[3]+para[4]*priceMB))
    probKR=exp(para[2]+para[4]*priceKR)/(1+exp(para[1]+para[4]*priceKB)+exp(para[2]+para[4]*priceKR)+exp(para[3]+para[4]*priceMB))
    probMB=exp(para[3]+para[4]*priceMB)/(1+exp(para[1]+para[4]*priceKB)+exp(para[2]+para[4]*priceKR)+exp(para[3]+para[4]*priceMB))
    return(cbind(probKB,probKR,probMB))
}

agg_choice=function(priceKB,priceKR,priceMB) {
    
    agg_choice=seg.share[1]*demand_3(priceKB,priceKR,priceMB,as.numeric(coef.est[1,2:5]))+
        seg.share[2]*demand_3(priceKB,priceKR,priceMB,as.numeric(coef.est[2,2:5]))+
        seg.share[3]*demand_3(priceKB,priceKR,priceMB,as.numeric(coef.est[3,2:5]))+
        seg.share[4]*demand_3(priceKB,priceKR,priceMB,as.numeric(coef.est[4,2:5]))+
        seg.share[5]*demand_3(priceKB,priceKR,priceMB,as.numeric(coef.est[5,2:5]))+ 
        seg.share[6]*demand_3(priceKB,priceKR,priceMB,as.numeric(coef.est[6,2:5]))+
        seg.share[7]*demand_3(priceKB,priceKR,priceMB,as.numeric(coef.est[7,2:5]))+
        seg.share[8]*demand_3(priceKB,priceKR,priceMB,as.numeric(coef.est[8,2:5]))+
        seg.share[9]*demand_3(priceKB,priceKR,priceMB,as.numeric(coef.est[9,2:5]))
    
    return(agg_choice)
}

#Average Price
avgPriceKB = mean(data$price.KB)
avgPriceKR = mean(data$price.KR)
avgPriceMB = mean(data$price.MB)
avgPrice=c(avgPriceKB,avgPriceKR,avgPriceMB)
#own elasticity 
#KB (KB price increase 1%, how does the demand of KB changes)
original = agg_choice(avgPrice[1], avgPrice[2], avgPrice[3])[1]
new = agg_choice(avgPrice[1]*1.01, avgPrice[2], avgPrice[3])[1]
ownElasticityKB_seg = ((new - original) / original) * -100
#KR
original = agg_choice(avgPrice[1], avgPrice[2], avgPrice[3])[2]
new = agg_choice(avgPrice[1], avgPrice[2]*1.01, avgPrice[3])[2]
ownElasticityKR_seg = ((new - original) / original) * -100
#MB
original = agg_choice(avgPrice[1], avgPrice[2], avgPrice[3])[3]
new = agg_choice(avgPrice[1], avgPrice[2], avgPrice[3]*1.01)[3]
ownElasticityMB_seg = ((new - original) / original) * -100

dfownElasticity_seg <- data.frame("Product"=c("KB","KR","MB"), 
                               "OwnElasticity"=c(ownElasticityKB_seg,ownElasticityKR_seg,ownElasticityMB_seg))
dfownElasticity_seg
##   Product OwnElasticity
## 1      KB      4.301270
## 2      KR      3.572349
## 3      MB      4.208459
#cross elasticity 
#KB
original = agg_choice(avgPrice[1], avgPrice[2], avgPrice[3])[1]
new1 = agg_choice(avgPrice[1], avgPrice[2]*1.01, avgPrice[3])[1]
new2 = agg_choice(avgPrice[1], avgPrice[2], avgPrice[3]*1.01)[1]
crossElasticityKB_KR_seg = ((new1 - original) / original) *100 #0.8969546
crossElasticityKB_MB_seg = ((new2 - original) / original) *100 #1.057054
crossElasticityKB = cbind(crossElasticityKB_KR_seg, crossElasticityKB_MB_seg)
crossElasticityKB
##      crossElasticityKB_KR_seg crossElasticityKB_MB_seg
## [1,]                0.8969546                 1.057054
#KR
original = agg_choice(avgPrice[1], avgPrice[2], avgPrice[3])[2]
new1 = agg_choice(avgPrice[1]*1.01, avgPrice[2], avgPrice[3])[2]
new2 = agg_choice(avgPrice[1], avgPrice[2], avgPrice[3]*1.01)[2]
crossElasticityKR_KB_seg = ((new1 - original) / original) *100 #0.7994986
crossElasticityKR_MB_seg = ((new2 - original) / original) *100 #0.8151528
crossElasticityKR = cbind(crossElasticityKR_KB_seg, crossElasticityKR_MB_seg)
crossElasticityKR
##      crossElasticityKR_KB_seg crossElasticityKR_MB_seg
## [1,]                0.7994986                0.8151528
#MB
original = agg_choice(avgPrice[1], avgPrice[2], avgPrice[3])[3]
new1 = agg_choice(avgPrice[1]*1.01, avgPrice[2], avgPrice[3])[3]
new2 = agg_choice(avgPrice[1], avgPrice[2]*1.01, avgPrice[3])[3]
crossElasticityMB_KB_seg = ((new1 - original) / original) *100 #1.020472
crossElasticityMB_KR_seg = ((new2 - original) / original) *100 #0.8830009
crossElasticityMB = cbind(crossElasticityMB_KB_seg, crossElasticityMB_KR_seg)
crossElasticityMB
##      crossElasticityMB_KB_seg crossElasticityMB_KR_seg
## [1,]                 1.020472                0.8830009

Comparing with the no-segmentation case, the own elasticity of KR decrease and the other two increases. For the cross elasticity, the elasticity between KB and MB increases, meaning that they are good substitutions. Therefore, the enter of KB does steal some demand from MB if MB’s price increase. For cross elasticity between KB and KR, the elasticity decreases. This means that when price of either product increases, it does not steal the demand from other product. Namely, it rules out the probability of cannibalization and the positioning did made a good impact on our products. The segments of customers are loyal to our product.

#Discuss the preference of the segments
differKB_KR = vector()
differKB_MB = vector()
differKR_MB = vector()

for (i in 1:9) {
    differKB_KR = append(differKB_KR, coef.est[i,2]-coef.est[i,3])
    differKB_MB = append(differKB_MB, coef.est[i,2]-coef.est[i,4])
    differKR_MB = append(differKR_MB, coef.est[i,3]-coef.est[i,4])
}

difference = data.frame(segments = c(1:9, "avg"),
                        differKB_KR = c(differKB_KR, mean(differKB_KR)),
                        differKB_MB = c(differKB_MB, mean(differKB_MB)),
                        differKR_MB = c(differKR_MB, mean(differKR_MB))
                        )

#Scatterplot KB vs. KR
plot(difference$differKB_KR[1:9], coef.est[,5], 
     main = ("KB vs. KR"),
     xlab="beta_0^KB-beta_0^KR",ylab=("beta_1"),
     xlim=c(-1.5,2),ylim=c(-6,-1),
     type='n')
points(difference$differKB_KR[1],coef.est$price.coef[1],cex=20*seg.share[1],col='orange',pch=16)
points(difference$differKB_KR[2],coef.est$price.coef[2],cex=20*seg.share[2],col='orange',pch=16)
points(difference$differKB_KR[6],coef.est$price.coef[6],cex=20*seg.share[6],col='orange',pch=16)
points(difference$differKB_KR[8],coef.est$price.coef[8],cex=20*seg.share[8],col='orange',pch=16)
points(difference$differKB_KR[3],coef.est$price.coef[3],cex=20*seg.share[3],col='blue',pch=16)
points(difference$differKB_KR[4],coef.est$price.coef[4],cex=20*seg.share[4],col='blue',pch=16)
points(difference$differKB_KR[5],coef.est$price.coef[5],cex=20*seg.share[5],col='blue',pch=16)
points(difference$differKB_KR[7],coef.est$price.coef[7],cex=20*seg.share[7],col='blue',pch=16)
points(difference$differKB_KR[9],coef.est$price.coef[9],cex=20*seg.share[9],col='blue',pch=16)

#Scatterplot KB vs. MB
plot(difference$differKB_MB[1:9], coef.est[,5], 
     main = ("KB vs. MB"),
     xlab="beta_0^KB-beta_0^MB",ylab=("beta_1"),
     xlim=c(-1.5,2),ylim=c(-6,-1),
     type='n')
points(difference$differKB_MB[3],coef.est$price.coef[3],cex=20*seg.share[3],col='orange',pch=16)
points(difference$differKB_MB[2],coef.est$price.coef[2],cex=20*seg.share[2],col='orange',pch=16)
points(difference$differKB_MB[4],coef.est$price.coef[4],cex=20*seg.share[4],col='orange',pch=16)
points(difference$differKB_MB[8],coef.est$price.coef[8],cex=20*seg.share[8],col='red',pch=16)
points(difference$differKB_MB[5],coef.est$price.coef[5],cex=20*seg.share[5],col='orange',pch=16)
points(difference$differKB_MB[9],coef.est$price.coef[9],cex=20*seg.share[9],col='orange',pch=16)
points(difference$differKB_MB[1],coef.est$price.coef[1],cex=20*seg.share[1],col='blue',pch=16)
points(difference$differKB_MB[7],coef.est$price.coef[7],cex=20*seg.share[7],col='blue',pch=16)
points(difference$differKB_MB[6],coef.est$price.coef[6],cex=20*seg.share[6],col='blue',pch=16)

#Scatterplot KR vs. MB
plot(difference$differKB_MB[1:9], coef.est[,5], 
     main = ("KR vs. MB"),
     xlab="beta_0^KR-beta_0^MB",ylab=("beta_1"),
     xlim=c(-1.5,2),ylim=c(-6,-1),
     type='n')
points(difference$differKR_MB[1],coef.est$price.coef[1],cex=20*seg.share[1],col='orange',pch=16)
points(difference$differKR_MB[2],coef.est$price.coef[2],cex=20*seg.share[2],col='orange',pch=16)
points(difference$differKR_MB[4],coef.est$price.coef[4],cex=20*seg.share[4],col='orange',pch=16)
points(difference$differKR_MB[6],coef.est$price.coef[6],cex=20*seg.share[6],col='orange',pch=16)
points(difference$differKR_MB[5],coef.est$price.coef[5],cex=20*seg.share[5],col='orange',pch=16)
points(difference$differKR_MB[8],coef.est$price.coef[8],cex=20*seg.share[8],col='orange',pch=16)
points(difference$differKR_MB[3],coef.est$price.coef[3],cex=20*seg.share[3],col='blue',pch=16)
points(difference$differKR_MB[7],coef.est$price.coef[7],cex=20*seg.share[7],col='blue',pch=16)
points(difference$differKR_MB[9],coef.est$price.coef[9],cex=20*seg.share[9],col='red',pch=16)

From the scatter plot, we can see that cluster 1,2,6, and 8, which is in the orange, have higher preference in KR. On the other hand, cluster3,4,5,7,9 have more preference in KB. Besides, the orange cluster has lower price sensitivity than the blue clusters, meaning that when the price of KB changes, it is possible that they will react the same. However, for the blue clusters, when the price of KB changes, they will probably change to KR for substitution.

By looking at the comparison with our rival product (MB). We see that for cluster 8, they have higher preference in KB and also with a low sensitivity. Therefore, we should target our product KB on cluster 8 customers since they are comparatively more loyal to the product.

Part C : Calculate Optimal Pricing

#KR and MB (not launching KB)
unit_cost=0.5
para_2=c(beta0KR,beta0MB,beta1)

demand_2=function(priceKR,priceMB,para_2){ 
    prob1=exp(para_2[1]+para_2[3]*priceKR)/(1+exp(para_2[1]+para_2[3]*priceKR)+exp(para_2[2]+para_2[3]*priceMB))
    prob2=exp(para_2[2]+para_2[3]*priceMB)/(1+exp(para_2[1]+para_2[3]*priceKR)+exp(para_2[2]+para_2[3]*priceMB))
    return(cbind(prob1,prob2))
}

agg_choice_2=function(priceKR,priceMB) { 
    agg_choice=seg.share[1]*demand_2(priceKR,priceMB,as.numeric(coef.est[1,3:5]))+
        seg.share[2]*demand_2(priceKR,priceMB,as.numeric(coef.est[2,3:5]))+
        seg.share[3]*demand_2(priceKR,priceMB,as.numeric(coef.est[3,3:5]))+
        seg.share[4]*demand_2(priceKR,priceMB,as.numeric(coef.est[4,3:5]))+
        seg.share[5]*demand_2(priceKR,priceMB,as.numeric(coef.est[5,3:5]))+ 
        seg.share[6]*demand_2(priceKR,priceMB,as.numeric(coef.est[6,3:5]))+
        seg.share[7]*demand_2(priceKR,priceMB,as.numeric(coef.est[7,3:5]))+
        seg.share[8]*demand_2(priceKR,priceMB,as.numeric(coef.est[8,3:5]))+
        seg.share[9]*demand_2(priceKR,priceMB,as.numeric(coef.est[9,3:5]))
    return(agg_choice)
}


pricespace=seq(1,3,0.01)
profit=1000*agg_choice_2(pricespace,1.43)[,1]*(pricespace-unit_cost)
priceKRBest=pricespace[profit==max(profit)] #best priceKR 1.06
profit_2_KR=max(profit) #profitKR 289.9052

profit_2_MB=1000*agg_choice_2(priceKRBest, 1.43)[,2]*(1.43-unit_cost)  #profitMB 105.6955
profit_2_KR
## [1] 289.9052
#KB, KR, and MB (launching KB)
profit_KB_KR_seg=function(priceKB,priceKR, priceMB,para){
    profitKB=1000*(agg_choice(priceKB,priceKR, priceMB)[,1]*(priceKB-unit_cost))
    profitKR=1000*(agg_choice(priceKB,priceKR, priceMB)[,2]*(priceKR-unit_cost))
    return(cbind(profitKB,profitKR))
}

aux=seq(1,3,0.01)
pricespace=expand.grid(aux,aux)

profitmat=matrix(0,nrow(pricespace),1)
for (i in 1:nrow(pricespace)){
    profitmat[i]=sum(profit_KB_KR_seg(pricespace[i,1],pricespace[i,2],1.43,para))  
}

profit_3_KB_KR = max(profitmat) #395.3924
priceKB_KR_Best=pricespace[profitmat==max(profitmat)]
priceKB_KR_Best
## [1] 1.15 1.19
profit_3_MB=1000*agg_choice(priceKB_KR_Best[1], priceKB_KR_Best[2], 1.43)[3]*(1.43-unit_cost) 
profit_3_MB 
## [1] 90.15035
priceKB_KR_Best
## [1] 1.15 1.19

Suppose we only launch Kiwi Regular, the optimal price for KR is 1.06, having the max profit 105.70. On the other hand, MB has a profit of 131.42.
If we launch Kiwi Bubble, the optimal price for KB and KR are 1.15 and 1.19 respectively. The optimal profit for Kiwi and Mango are 395.39 and 103.82.
We can see that Mango has decreased 1.88 for it’s profit. With an increase in our profits, we should launch KB. Based on our model from the previous question, we can see that when comparing KB and MB, segment 1,7 and 6 are more prefer to MB.
On the other hand, when comparing KR and MB, cluster 3 and 7 prefer MB more. Therefore, when we launch both KR and KB, our strategy could be positioning KR and KB on clusters without cluster 7. Which means that we could steal profit from MB on cluster 3 if we launched KB.

#Calculate MB’s optimal price given KB and KR ’s optimal prices
pricespace=seq(0.5,3,0.01)
profitMB = 1000*agg_choice(priceKB_KR_Best[1],priceKB_KR_Best[2],pricespace)[,3]*(pricespace-unit_cost)
priceMBBest=pricespace[profitMB==max(profitMB)] #0.96
profit_MB=max(profitMB) #180.4173
profit_MB
## [1] 180.4173

If MB reacts to the new price of Kiwi, it would charge MB for $0.96

#React to MB’s new price, set new price for KB and KR
#Round 1: KB_KR
ux=seq(0.5,3,0.01)
pricespace=expand.grid(aux,aux)
profitmat2=matrix(0,nrow(pricespace),1)

for (i in 1:nrow(pricespace)){
    profitmat2[i]=sum(profit_KB_KR_seg(pricespace[i,1],pricespace[i,2],priceMBBest,para))  
}

profit_4_KB_KR = max(profitmat2) 
priceKB_KR_Best2=pricespace[profitmat2==max(profitmat2)]
priceKB_KR_Best2 #kB:1.02 kR:1.08
## [1] 1.02 1.08

To respond to the new price of Mango Bubble, the Kiwi would charge KB $1.02 and KR $1.08

#Repeat previous two steps, until reach "equilibrium price"
#Round 2:MB
pricespace=seq(0.5,3,0.01)
profitMB = 1000*agg_choice(priceKB_KR_Best2[1],priceKB_KR_Best2[2],pricespace)[,3]*(pricespace-unit_cost)
priceMBBest2=pricespace[profitMB==max(profitMB)] #0.92
profit_MB=max(profitMB) # 147.7467

#Round 2: KB_KR
ux=seq(0.5,3,0.01)
pricespace=expand.grid(aux,aux)
profitmat3=matrix(0,nrow(pricespace),1)

for (i in 1:nrow(pricespace)){
    profitmat3[i]=sum(profit_KB_KR_seg(pricespace[i,1],pricespace[i,2],priceMBBest2,para))  
}

profit_5_KB_KR = max(profitmat3) 
priceKB_KR_Best3=pricespace[profitmat3==max(profitmat3)]
priceKB_KR_Best3 #kB:1.01 kR:1.07
## [1] 1.01 1.07
#Round 3: MB
pricespace=seq(0.5,3,0.01)
profitMB = 1000*agg_choice(priceKB_KR_Best3[1],priceKB_KR_Best3[2],pricespace)[,3]*(pricespace-unit_cost)
priceMBBest3=pricespace[profitMB==max(profitMB)] #0.91
profit_MB=max(profitMB) #145.0344

#Round 3: KB_KR
ux=seq(0.5,3,0.01)
pricespace=expand.grid(aux,aux)
profitmat4=matrix(0,nrow(pricespace),1)

for (i in 1:nrow(pricespace)){
    profitmat4[i]=sum(profit_KB_KR_seg(pricespace[i,1],pricespace[i,2],priceMBBest3,para))  
}

profit_6_KB_KR = max(profitmat4) #259.7019
priceKB_KR_Best4=pricespace[profitmat4==max(profitmat4)]
priceKB_KR_Best4 #kB:1.01 kR:1.07
## [1] 1.00 1.07

The new “equilibrium price” for KB,KR and MB are $1.02, $1.08 and $0.91 respectively

#maket share with KB
agg_choice(1.01,1.07,0.91)
##         probKB    probKR    probMB
## [1,] 0.2542026 0.2281623 0.3537424
#market share without KB
agg_choice_2(1.06,1.43)
##          prob1     prob2
## [1,] 0.5176879 0.1146273

After several rounds of “Pricing War”,neither Kiwi nor Mango has an incentive to set a different price. The ultimate prices of KB and KR are $1.01 and $1.07 respectively.And the ultimate price of MB is 0.91.

With the launch of KB, instead of increasing profit, the profit of Kiwi decrease, since the KB steals market share from KR but not MB. So, after going through the “Pricing War”, the launch of KB would not help Kiwi stealing market share from MB.

It may be profitable for kiwi if MB could not afford such hugh change in prices (from 1.43 - 0.91),for example, the fixed costs of MB may be higher than 0.91.